#include "flowview.h"
#include <QFontMetrics>
#include <QMouseEvent>
#include <QPushButton>

FlowView::FlowView(QWidget* parent) : QFrame { parent } { }

void FlowView::setSpacing(int spacing)
{
    spacing_ = spacing;
    layoutItems();
}

void FlowView::setUseSizeHint(bool use)
{
    use_size_hint_ = use;
    layoutItems();
}

QWidget* FlowView::itemAt(const QPoint& mpos) const
{
    QPoint mpos_in_panel = mapFromGlobal(mapToGlobal(mpos));
    for (auto p : items_) {
        if (p->geometry().contains(mpos_in_panel)) {
            return p;
        }
    }
    return nullptr;
}

void FlowView::addItem(QWidget* item)
{
    Q_ASSERT(item);
    if (item) {
        items_.push_back(item);
        item->setParent(this);
        if (testAttribute(Qt::WA_WState_Visible)) {
            item->show();
        }
        layoutItems();
    }
}

void FlowView::addItems(const QList<QWidget*>& items)
{
    if (!items.empty()) {
        for (auto i : items) {
            items_.push_back(i);
            i->setParent(this);
            i->show();
        }
        layoutItems();
    }
}

void FlowView::setItems(const QList<QWidget*>& items, int from)
{
    bool need_layout = false;
    if (!items_.empty()) {
        for (int i = items_.size() - 1; i >= from; --i) {
            if (!items.contains(items_.at(i))) {
                items_.at(i)->deleteLater();
            }
            items_.removeAt(i);
        }
        need_layout = true;
    }
    if (!items.empty()) {
        addItems(items);
    } else if (need_layout) {
        layoutItems();
    }
}

void FlowView::takeItems(const QList<QWidget*>& items)
{
    for (QWidget* p : items) {
        items_.removeOne(p);
    }
    layoutItems();
}

void FlowView::removeItem(QWidget* item)
{
    if (items_.removeOne(item)) {
        layoutItems();
    }
}

void FlowView::removeItems(int from)
{
    for (int i = items_.size() - 1; i >= from; --i) {
        items_.takeAt(i)->deleteLater();
    }
    layoutItems();
}

void FlowView::layoutItems()
{
    if (!items_.empty()) {
        const QSize view_size = size();
        int x = 0, y = 0, max_h = 0;
        for (QWidget* p : items_) {
            const QSize item_size = use_size_hint_ ? p->sizeHint() : p->size();
            if (x > 0 && ((x + item_size.width()) > view_size.width())) {
                x = 0;
                y += max_h + spacing_;
                max_h = item_size.height();
            } else {
                if (max_h < item_size.height()) {
                    max_h = item_size.height();
                }
            }
            p->setGeometry(QRect(x, y, item_size.width(), item_size.height()));
            x += item_size.width() + spacing_;
        }
    }
}

void FlowView::clear()
{
    for (QWidget* p : items_) {
        p->deleteLater();
    }
    items_.clear();
}

int FlowView::heightForWidth(int w) const
{
    if (items_.empty()) {
        return 0;
    } else {
        int x = 0, y = 0, max_h = 0;
        for (QWidget* p : items_) {
            const QSize item_size = use_size_hint_ ? p->sizeHint() : p->size();
            if (x > 0 && ((x + item_size.width()) > w)) {
                x = item_size.width() + spacing_;
                y += max_h + spacing_;
                max_h = item_size.height();
            } else {
                x += item_size.width() + spacing_;
                if (max_h < item_size.height()) {
                    max_h = item_size.height();
                }
            }
        }
        return (y + max_h);
    }
}

void FlowView::resizeEvent(QResizeEvent* re)
{
    QFrame::resizeEvent(re);
    layoutItems();
}
